﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CoreUtils.WIL
{
    /// <summary>
    /// Hough functions from WIL library
    /// </summary>
    public class Hough
    {
        public static FVIL.Data.CFviImage CircleHoughCorrelationEdge(FVIL.Data.CFviImage src,
            double rMin, double rMax)
        {
            FVIL.Hough.CFviCircleHoughCorrelationEdge parser =
                new FVIL.Hough.CFviCircleHoughCorrelationEdge();
            src = Conversion.toGrayScale(src, 0.299, 0.587, 0.114);
            int valid = FVIL.Hough.CFviCircleHoughCorrelationEdge.CheckValidity(src);
            if (FVIL.ErrorCode._SUCCESS != valid)
                throw new FVIL.CFviException(valid, "FVIL.Hough.CFviCircleHoughCorrelationEdge.CheckValidity");
            parser.SrcImages[0] = src;

            FVIL.Hough.CFviCircleHoughParam param = parser.Param;
            param.Resolution = 1.0;
            param.RadiusMin = rMin;
            param.RadiusMax = rMax;
            param.QRange = 30;
            param.EdgePercent = 20;
            param.MinScore = 8;
            param.ObjectColor = FVIL.Hough.ObjectColor.BlackOrWhite;
            param.MergeCenter = 2;
            param.MergeRadius = 1;

            FVIL.Edge.CFviEdge2DCorrelationParam param_edge = parser.ParamEdge;
            param_edge.RegionWidth = 13;
            param_edge.RegionHeight = 5;
            param_edge.SigmoidK = 1.0;
            param_edge.VarThreshold = 20.0;
            param_edge.EdgeThreshold = 40;
            param_edge.NmsLength = 6;

            try
            {
                parser.Execute();
            }
            catch (System.Exception ex)
            {
                throw new Exception(ex.Message);
            }
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            {
                FVIL.GDI.CFviDisplay display = new FVIL.GDI.CFviDisplay();
                display.Image = src;
                display.DisplayRect = src.Window;

                FVIL.GDI.CFviOverlay pOverlay0 = new FVIL.GDI.CFviOverlay();
                pOverlay0.Scaling = true;
                display.Overlays.Add(pOverlay0);

                for (int i = 0; i < parser.Result.Count; i++)
                {
                    FVIL.Hough.CFviCircleHoughData data = parser.Result[i];
                    FVIL.GDI.CFviGdiCircle circle = new FVIL.GDI.CFviGdiCircle(data.ToCFviCircle());
                    circle.Pen.Color = System.Drawing.Color.Red;
                    circle.Pen.Width = 3;
                    pOverlay0.Figures.Add(circle);
                }
                display.SaveImage(dst, display.DisplayRect, 1.0);
            }
            return dst;
        }

        public static FVIL.Data.CFviImage LineHoughCorrelationEdge(FVIL.Data.CFviImage src,
            int requestNb)
        {
            FVIL.Hough.CFviLineHoughCorrelationEdge parser =
                new FVIL.Hough.CFviLineHoughCorrelationEdge();
            int valid = FVIL.Hough.CFviLineHoughCorrelationEdge.CheckValidity(src);
            if (FVIL.ErrorCode._SUCCESS != valid)
                throw new FVIL.CFviException(valid, "FVIL.Hough.CFviLineHoughCorrelationEdge.CheckValidity");
            parser.SrcImages[0] = src;
            FVIL.Hough.CFviLineHoughParam param = parser.Param;
            param.RequestNum = requestNb;
            param.AngleSt = new FVIL.Data.CFviAngle(0.0);
            param.AngleEd = new FVIL.Data.CFviAngle(359.0);
            param.VoteWidth = 10;
            param.RegionR = 10;
            param.RegionQ = 10;

            FVIL.Edge.CFviEdge2DCorrelationParam param_edge = parser.ParamEdge;
            param_edge.RegionWidth = 13;
            param_edge.RegionHeight = 5;
            param_edge.SigmoidK = 1.0;
            param_edge.VarThreshold = 25.0;
            param_edge.EdgeThreshold = 40;
            param_edge.NmsLength = 6;

            try
            {
                parser.Execute();
            }
            catch (System.Exception ex)
            {
                throw new Exception(ex.Message);
            }
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            {
                FVIL.GDI.CFviDisplay display = new FVIL.GDI.CFviDisplay();
                display.Image = src;
                display.DisplayRect = src.Window;

                FVIL.GDI.CFviOverlay pOverlay0 = new FVIL.GDI.CFviOverlay();
                pOverlay0.Scaling = true;
                display.Overlays.Add(pOverlay0);

                for (int i = 0; i < parser.Result.Count; i++)
                {
                    FVIL.Hough.CFviLineHoughData data = parser.Result[i];
                    FVIL.GDI.CFviGdiLine line = new FVIL.GDI.CFviGdiLine(data.ToCFviLine());
                    line.Pen.Color = System.Drawing.Color.Red;
                    line.Pen.Width = 3;
                    pOverlay0.Figures.Add(line);
                }
                display.SaveImage(dst, display.DisplayRect, 1.0);
            }
            return dst;
        }

    }
}
